package com.cscp.javastudy.designpattern.singleton.demo1;

/**
 * 懒汉式单例
 */
public class LazyMan {

    private LazyMan() {
        System.out.println("Thread Name : " + Thread.currentThread().getName() + " OK");
    }

    // volatile必须要有，volatile保证了指令不会被重排序，从而保证了原子性操作
    private volatile static LazyMan lazyMan;

    /**
     * 双重检测锁模式 DCL懒汉式
     * @return
     */
    public static LazyMan getInstance(){
        // 位置1
        if (lazyMan == null) {
            synchronized (LazyMan.class) {
                if (lazyMan == null) {
                    /*
                     * 下面这样new LazyMan()的执行分析
                     * 1- 分配内存空间
                     * 2- 执行构造方法，初始化对象
                     * 3- 把这个对象指向这个空间
                     * 期望的指令执行循序是：123
                     * 假如执行被重排序了，执行顺序是132，此时，当执行了3后(此时2还没被执行),对象已经指向了空间(但没有被初始化因为2还没有执行).
                     * 此时加入有一个线程B来到了位置1，线程B就会发现lazyMan对象已经不为null了(此时还没有被初始化，因为2还没有执行)，线程B就会
                     * 拿走未被初始化的对象lazyMan从而引发问题
                     */
                    lazyMan = new LazyMan();
                }
            }
        }
        return lazyMan;
    }


}
